package com.example.test.dialogfactory;

import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.LayoutParams;
import androidx.recyclerview.widget.RecyclerView.State;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import easier.recycler.BaseViewHolder;
import easier.recycler.MultiTypeAdapter;
import easier.recycler.TypeViewHolder;
import java.util.ArrayList;
import java.util.List;

public class MainActivity90 extends AppCompatActivity {

    private RecyclerView recycler;
    private DataSource mDataSource = new DataSource();

    public static void start( Context context ) {

        Intent starter = new Intent( context, MainActivity90.class );
        context.startActivity( starter );
    }

    @Override
    protected void onCreate( Bundle savedInstanceState ) {

        super.onCreate( savedInstanceState );
        setContentView( R.layout.activity_main90 );
        initView();
    }

    private void initView() {

        recycler = (RecyclerView) findViewById( R.id.recycler );
        recycler.setLayoutManager( new LinearLayoutManager( this ) );
        recycler.setAdapter( new MultiTypeAdapter( convert() ) );

        Decoration decoration = new Decoration();
        recycler.addItemDecoration( decoration );
    }

    private List< TypeViewHolder > convert() {

        ArrayList< TypeViewHolder > list = new ArrayList<>();

        for ( String s : mDataSource.mData ) {
            list.add( new BaseViewHolder( R.layout.recycler_item_group ) {
                @Override
                protected void onBind( ViewHolder viewHolder, View root, int position, int type, List< Object > payloads ) {

                    super.onBind( viewHolder, root, position, type, payloads );
                    ((TextView) root.findViewById( R.id.text )).setText( s );
                    ((TextView) root.findViewById( R.id.desc )).setText( s + " desc" );
                }
            } );
        }

        return list;
    }

    private class DataSource {

        private String[] mData = {
            "AA",
            "AB",
            "AC",
            "AD",
            "BA",
            "BB",
            "BC",
            "BD",
            "CA",
            "CB",
            "CC",
            "CD",
            "DA",
            "DB",
            "DC",
            "DD"
        };

        private String get( int position ) {

            return mData[position];
        }

        private int getSize() {

            return mData.length;
        }

        private char getGroup( int position ) {

            return mData[position].charAt( 0 );
        }

        private boolean isFirstElementOfGroup( int position ) {

            if ( position == 0 ) {
                return true;
            }

            int last = position - 1;
            return getGroup( position ) != getGroup( last );
        }

        private boolean isLastElementOfGroup( int position ) {

            if ( position == mData.length ) {
                return true;
            }

            int next = position + 1;
            return getGroup( position ) != getGroup( next );
        }
    }

    private class Decoration extends RecyclerView.ItemDecoration {

        int mDecorationHeight = 100;

        private Paint mPaint = new Paint( Paint.ANTI_ALIAS_FLAG );
        private Paint mTextPaint = new Paint( Paint.ANTI_ALIAS_FLAG );

        private Decoration() {

            mPaint.setColor( Color.RED );
            mTextPaint.setColor( Color.WHITE );
            mTextPaint.setTextSize( mDecorationHeight * 0.8f );
        }

        @Override
        public void getItemOffsets(
            @NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull State state ) {

            super.getItemOffsets( outRect, view, parent, state );

            int position = ((LayoutParams) view.getLayoutParams()).getViewLayoutPosition();
            if ( mDataSource.isFirstElementOfGroup( position ) ) {
                outRect.top = mDecorationHeight;
            }
        }

        @Override
        public void onDrawOver(
            @NonNull Canvas c, @NonNull RecyclerView parent, @NonNull State state ) {

            super.onDrawOver( c, parent, state );

            View first = null;

            int childCount = parent.getChildCount();
            for ( int i = childCount - 1; i > 0; i-- ) {
                View child = parent.getChildAt( i );
                int position = ((LayoutParams) child.getLayoutParams()).getViewLayoutPosition();
                if ( mDataSource.isFirstElementOfGroup( position ) ) {
                    drawText( c, child, mDataSource.getGroup( position ) );
                }
            }

            View child = parent.getChildAt( 0 );

            if ( child != null ) {

                int top = child.getTop() - mDecorationHeight;
                int bottom = child.getTop();
                if ( top < 0 ) {
                    top = 0;
                    bottom = mDecorationHeight;
                }

                int position = ((LayoutParams) child.getLayoutParams()).getViewLayoutPosition();
                if ( mDataSource.isLastElementOfGroup( position ) ) {
                    if ( bottom > child.getBottom() ) {
                        bottom = child.getBottom();
                        top = bottom - mDecorationHeight;
                    }
                }
                c.drawRect(
                    child.getLeft(),
                    top,
                    child.getRight(),
                    bottom,
                    mPaint
                );

                float offset = BaseLineUtils.getBaselineOffset( mTextPaint );
                float y = (top + bottom) / 2f + offset;
                c.drawText( String.valueOf( mDataSource.getGroup( position ) ), child.getLeft(), y, mTextPaint );
            }
        }

        private void drawText( Canvas c, View child, char text ) {

            int top = child.getTop() - mDecorationHeight;
            int bottom = child.getTop();

            c.drawRect(
                child.getLeft(),
                top,
                child.getRight(),
                bottom,
                mPaint
            );

            float offset = BaseLineUtils.getBaselineOffset( mTextPaint );
            float y = (top + bottom) / 2f + offset;
            c.drawText( String.valueOf( text ), child.getLeft(), y, mTextPaint );
        }
    }

    public static class BaseLineUtils {

        public static float getBaselineOffset( Paint paint ) {

            FontMetrics fontMetrics = paint.getFontMetrics();
            float leading = fontMetrics.leading;
            float ascent = fontMetrics.ascent;
            float descent = fontMetrics.descent;

            return (descent - ascent - leading) / 2 - descent;
        }
    }
}